using Rogan.Utility.Common;
using Rogan.Utility.Extensions;
using Rogan.Data.Resources;
using System.Collections.Generic;
using System.Data.Common;
using System.Text;
namespace Rogan.Data
{
	public class CommandBulider
	{
		private Database db;
		private int paramCounter;
		private DbProvider dbProvider
		{
			get
			{
				return db.DbProvider;
			}
		}
		private ExpressionTranslater CreateTranslater()
		{
			return new ExpressionTranslater(dbProvider);
		}
		public CommandBulider(Database db)
		{
			this.db = db;
		}
		private string CreateParmName()
		{
			return "p" + ++paramCounter;
		}
		public DbCommand CreateUpdateCommand<T>(T entity, WhereExpression where) where T : Entity
		{
			List<Field> changedFields = entity.GetChangedFields();
			if (changedFields == null || changedFields.Count == 0)
			{
				return null;
			}
			object[] array = new object[changedFields.Count];
			int i = 0;
			int count = changedFields.Count;
			while (i < count)
			{
				array[i] = entity.GetValue(changedFields[i].PropertyName);
				i++;
			}
			return CreateUpdateCommand<T>(changedFields.ToArray(), array, where);
		}
		public DbCommand CreateUpdateCommand<T>(Field[] fields, object[] values, WhereExpression where) where T : Entity
		{
			Guard.Check(!EntityHelper.IsReadOnly<T>(), TextResource.CanNotReadOnly.FormatWith(new object[]
			{
				EntityHelper.GetName<T>()
			}));
			if (fields == null || fields.Length == 0 || values == null || values.Length == 0)
			{
				return null;
			}
			Guard.Check(fields.Length == values.Length, TextResource.ArgumentShouldEqual.FormatWith(new object[]
			{
				"字段的个数",
				"值的个数"
			}));
			int num = fields.Length;
			Field identityField = EntityHelper.GetIdentityField<T>();
			bool flag = !Field.IsNullOrEmpty(identityField);
			if (WhereExpression.IsNullOrEmpty(where))
			{
				where = WhereExpression.All;
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(" UPDATE ");
			stringBuilder.Append(db.DbProvider.BuildTableName(EntityHelper.GetName<T>()));
			stringBuilder.Append(" SET ");
			List<QueryParameter> list = new List<QueryParameter>();
			StringBuilder stringBuilder2 = new StringBuilder();
			bool flag2 = false;
			for (int i = 0; i < num; i++)
			{
				if (!flag || !fields[i].PropertyName.Equals(identityField.PropertyName))
				{
					if (flag2)
					{
						stringBuilder2.Append(",");
					}
					flag2 = true;
					stringBuilder2.Append(fields[i].FieldName);
					stringBuilder2.Append("=");
					if (values[i] is Field)
					{
						Field field = (Field)values[i];
						stringBuilder2.Append(field.FieldNameWithTable);
					}
					else
					{
						string text = CreateParmName();
						stringBuilder2.Append(text);
						QueryParameter item = new QueryParameter(text, values[i]);
						list.Add(item);
					}
				}
			}
			stringBuilder.Append(stringBuilder2);
			ExpressionTranslater expressionTranslater = CreateTranslater();
			stringBuilder.Append(" WHERE ");
			stringBuilder.Append(expressionTranslater.TranslateWhere(where));
			list.AddRange(expressionTranslater.Params);
			DbCommand sqlStringCommand = db.GetSqlStringCommand(stringBuilder.ToString());
			db.AddCommandParameter(sqlStringCommand, list.ToArray());
			return sqlStringCommand;
		}
		public DbCommand CreateDeleteCommand(string tableName, WhereExpression where)
		{
			if (WhereExpression.IsNullOrEmpty(where))
			{
				where = WhereExpression.All;
			}
			ExpressionTranslater expressionTranslater = CreateTranslater();
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(" DELETE FROM");
			stringBuilder.Append(db.DbProvider.BuildTableName(tableName));
			stringBuilder.Append(" WHERE ");
			stringBuilder.Append(expressionTranslater.TranslateWhere(where));
			DbCommand sqlStringCommand = db.GetSqlStringCommand(stringBuilder.ToString());
			db.AddCommandParameter(sqlStringCommand, expressionTranslater.Params.ToArray());
			return sqlStringCommand;
		}
		public DbCommand CreateDeleteCommand<T>(WhereExpression where) where T : Entity
		{
			return CreateDeleteCommand(EntityHelper.GetName<T>(), where);
		}
		public DbCommand CreateInsertCommand<T>(Field[] fields, object[] values) where T : Entity
		{
			Guard.Check(!EntityHelper.IsReadOnly<T>(), TextResource.CanNotReadOnly.FormatWith(new object[]
			{
				EntityHelper.GetName<T>()
			}));
			if (fields == null || fields.Length == 0 || values == null || values.Length == 0)
			{
				return null;
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(" INSERT INTO ");
			stringBuilder.Append(db.DbProvider.BuildTableName(EntityHelper.GetName<T>()));
			stringBuilder.Append(" (");
			Field identityField = EntityHelper.GetIdentityField<T>();
			bool flag = !Field.IsNullOrEmpty(identityField);
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			List<QueryParameter> list = new List<QueryParameter>();
			int num = fields.Length;
			for (int i = 0; i < num; i++)
			{
				if (!flag || !fields[i].PropertyName.Equals(identityField.PropertyName))
				{
					string text = CreateParmName();
					dictionary.Add(fields[i].FieldName, text);
					QueryParameter item = new QueryParameter(text, values[i], fields[i].ParameterDbType, fields[i].ParameterSize);
					list.Add(item);
				}
			}
			StringBuilder stringBuilder2 = new StringBuilder();
			StringBuilder stringBuilder3 = new StringBuilder();
			foreach (KeyValuePair<string, string> current in dictionary)
			{
				stringBuilder2.Append(",");
				stringBuilder2.Append(current.Key);
				stringBuilder3.Append(",");
				stringBuilder3.Append(current.Value);
			}
			stringBuilder.Append(stringBuilder2.ToString().Substring(1));
			stringBuilder.Append(")  VALUES  (");
			stringBuilder.Append(stringBuilder3.ToString().Substring(1));
			stringBuilder.Append(")");
			DbCommand sqlStringCommand = db.GetSqlStringCommand(stringBuilder.ToString());
			db.AddCommandParameter(sqlStringCommand, list.ToArray());
			return sqlStringCommand;
		}
		public DbCommand CreateInsertCommand<T>(T entity) where T : Entity
		{
			if (entity == null)
			{
				return null;
			}
			List<Field> changedFields = entity.GetChangedFields();
			if (changedFields == null || changedFields.Count == 0)
			{
				return CreateInsertCommand<T>(entity.GetFields(), entity.GetValues());
			}
			object[] array = new object[changedFields.Count];
			for (int i = 0; i < changedFields.Count; i++)
			{
				array[i] = entity.GetValue(changedFields[i].PropertyName);
			}
			return CreateInsertCommand<T>(changedFields.ToArray(), array);
		}
	}
}
